//
//  vector3.h
//  GLDemo
//
//  Created by wneqi on 14-5-30.
//  Copyright (c) 2014年 xiewneqi. All rights reserved.
//

#ifndef __GLDemo__vector3__
#define __GLDemo__vector3__

#include "common_header.h"
#include <iostream>

class Vector3
{
public: // constructors and destructors
    
    Vector3 ();
    
    Vector3 (GLfloat x, GLfloat y, GLfloat z);
    
    ~Vector3 ();
    
public: // getters and setters
    
    GLfloat GetMagnitude () const;
    
    Vector3 GetNormalized () const;
    
    GLfloat GetSqrMagnitude () const;
    
    void Normalize ();
    
public: // methods
    
    void Set (GLfloat x, GLfloat y, GLfloat z);
    
    void SetX (GLfloat x);
    
    void SetY (GLfloat y);
    
    void SetZ (GLfloat z);
    
    GLfloat GetX () const;
    
    GLfloat GetY () const;
    
    GLfloat GetZ () const;
    
public: // operators
    
    GLfloat& operator[] (int i);
    
    const GLfloat& operator[] (int i) const;
    
    Vector3 operator - () const;
    
    Vector3 operator + (const Vector3& v) const;
    
    Vector3 operator - (const Vector3& v) const;
    
    Vector3 operator * (const GLfloat s) const;
    
    Vector3 operator / (const GLfloat s) const;
    
    bool operator == (const Vector3& v) const;
    
    bool operator != (const Vector3& v) const;
    
    friend std::ostream& operator << (std::ostream& stream, const Vector3& v);
    
public: // static members
    static const Vector3 back;
    
    static const Vector3 down;
    
    static const Vector3 forward;
    
    static const Vector3 left;
    
    static const Vector3 one;
    
    static const Vector3 right;
    
    static const Vector3 up;
    
    static const Vector3 zero;
    
public: // static functions
    
    static GLfloat AngleBetween (const Vector3& from, const Vector3& to);
    
    static Vector3 ClampMagnitude (const Vector3& v, GLfloat maxLength);
    
    static Vector3 Cross (const Vector3& left, const Vector3& right);
    
    static GLfloat Distance (const Vector3& from , const Vector3& to);
    
    static GLfloat Dot (const Vector3& left, const Vector3& right);
    
    static Vector3 Lerp (const Vector3& left, const Vector3& right, GLfloat t);
    
    static Vector3 Max (const Vector3& left, const Vector3& right);
    
    static Vector3 Min (const Vector3& left, const Vector3& right);
    
    static Vector3 MoveTowards (const Vector3& current, const Vector3& target, GLfloat maxDistanceDelta);
    
    static void OrthoNormalize (Vector3& normal, Vector3& tagent);
    static Vector3 Project (const Vector3& vector, const Vector3& onNormal);
    
    static Vector3 Reflect (const Vector3& inDirection, const Vector3& inNormal);
    
    static Vector3 RotateTowards (const Vector3& current, const Vector3& target, GLfloat maxRadiansDelta, GLfloat maxMagnitudeDelta);
    
    static Vector3 Scale (const Vector3& a, const Vector3& b);
    
    static Vector3 Slerp (const Vector3& from, const Vector3&to, GLfloat t);
    
private: // private members
    
    GLfloat m_x;
    GLfloat m_y;
    GLfloat m_z;
};

#endif /* defined(__GLDemo__vector3__) */
